#include "WidgetVariantContainer.h"
#include <QtCore/QVariant>
#include <iostream>
#include <QComboBox>
#include <QDoubleSpinBox>
#include <QSpinBox>
#include <WidgetsManager.h>
#include <WidgetVariantGroup.h>
#include <WidgetVariantBool.h>
#include <WidgetVariantColor.h>
#include <WidgetVariantDouble.h>
#include <WidgetVariantInt.h>
#include <WidgetVariantMatrix.h>
#include <WidgetVariantString.h>
#include <WidgetVariantVec2.h>
#include <WidgetVariantVec3.h>
#include <WidgetVariantVec4.h>
#include <WidgetVariantButton.h>
#include <WidgetVariantFunction.h>
#include "DefineCommon.h"
#include "ui_WidgetVariantContainer.h"

WidgetVariantContainer::WidgetVariantContainer(QWidget *parent):
    QWidget(parent),
    ui(new Ui::WidgetVariantContainer)
{
    ui->setupUi(this);
	buildThis();

    QObject::connect(ui->buttonSearch, 
                     SIGNAL(clicked(bool)),
                     this, 
                     SLOT(slotButtonSearchClicked(bool)));
    QObject::connect(ui->buttonRefresh, 
                     SIGNAL(clicked(bool)),
                     this, 
                     SLOT(slotButtonRefresh(bool)));

    this->m_controllerProperty = NewSmartPtr(EControllerQtProperty)();
}

WidgetVariantContainer::~WidgetVariantContainer()
{
    
}

void WidgetVariantContainer::addWidget(QWidget* widget_ptr)
{
	/*int lay_out_count = m_layout->count();
	m_layout->insertWidget(lay_out_count - 1, widget_ptr);
	widget_ptr->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));*/

    if(widget_ptr != NULL)
    {
		int count = m_layout->count();
		//m_layout->removeItem(m_layout->itemAt(count - 1));
        //m_layout->addWidget(widget_ptr);
		m_layout->insertWidget(count-1, widget_ptr);
        m_widgetList.push_back(widget_ptr);

        QObject::connect(widget_ptr,
                        SIGNAL(signalVariantChanged( EItemMetaPropertyPtr )),
                        this,
                        SLOT(slotSubVariantWidgetChanged(EItemMetaPropertyPtr  ))
                        );
		
    }

}

QWidget *WidgetVariantContainer::getWidget(int index)
{
	QWidget* widgetPtr = NULL;
	if (index >= 0 && index < m_widgetList.size())
	{
		widgetPtr = m_widgetList.at(index);
	}
	return widgetPtr;
}

QVBoxLayout *WidgetVariantContainer::getTheLayout()
{
	return m_layout;
}


void WidgetVariantContainer::cleanAllWidget()
{
	/**/int i;
	for (i = 0; i < m_widgetList.size(); i++)
	{
		m_widgetList[i]->disconnect();
		m_layout->removeWidget(m_widgetList[i]);
		
		delete m_widgetList[i];
	}
	
	m_widgetList.clear();
}

void WidgetVariantContainer::filtWidget(const QString& filterStr)
{
    // for(int i = 0 ; i < m_widgetList.size(); i++)
    // {
        // WidgetVariant* w = dynamic_cast<WidgetVariant*>(m_widgetList[i]);
        // if(w != NULL)
        // {
           // QString wFilterStr = w->getProperty().name;
           // if(filterStr == "*" || filterStr == "")
           // {
               // w->setHidden(false);
           // }
           // else if(wFilterStr.contains(filterStr))
           // {
               // w->setHidden(false);
           // }
           // else 
           // {
               // w->setHidden(true);
           // }
        // }
    // }
}

void WidgetVariantContainer::buildThis()
{
	ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	QSizePolicy scroll_sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
	ui->scrollArea->setSizePolicy(scroll_sizePolicy);
	
    QWidget* widget_ptr = new QWidget;
	widget_ptr->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
	ui->scrollArea->setWidget(widget_ptr);
	m_layout = new QVBoxLayout;
	widget_ptr->setLayout(m_layout);
	m_layout->setSizeConstraint(QLayout::SizeConstraint::SetMinimumSize);
	//m_layout->addStretch();
	m_layout->setContentsMargins(0, 0, 0, 0);
	m_layout->setSpacing(2);
	QSpacerItem* verticalSpacer = new QSpacerItem(20, 250, QSizePolicy::Minimum, QSizePolicy::Expanding);
	m_layout->addItem(verticalSpacer);
	//widget_ptr->setProperty("backGround_2", QVariant(true));
	/*widget_ptr->setStyleSheet("QWidget *[backGround_2=\"true\"]\n"
		"{\n"
		"	background-color: rgb(70, 70, 70);\n"
		"}\n");
*/
	/////////////////////////////
	ui->scrollArea->setWidgetResizable(true);
	//setMinimumHeight(450);
	ui->scrollArea->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Preferred);

	ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
	ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
}

void WidgetVariantContainer::installEventFilterForChildren()
{
    {
        QList<QComboBox*> wList = this->findChildren<QComboBox*>();
        for(int i = 0 ; i < wList.size(); i++)
        {
            wList[i]->installEventFilter(this);
        }
    }
    {
        QList<QDoubleSpinBox*> wList = this->findChildren<QDoubleSpinBox*>();
        for(int i = 0 ; i < wList.size(); i++)
        {
            wList[i]->installEventFilter(this);
        }
    }
    {
        QList<QSpinBox*> wList = this->findChildren<QSpinBox*>();
        for(int i = 0 ; i < wList.size(); i++)
        {
            wList[i]->installEventFilter(this);
        }
    }
}

EControllerPtr WidgetVariantContainer::getController()
{
    return this->m_controllerProperty;
}

void WidgetVariantContainer::slotSelectItemBase(EItemPtr ibp)
{
	// this->cleanAllWidget();
    // this->m_itemBasePtr = ibp;
    // m_itemBasePtr->updateToPropertyAll();

    // if(ibp == nullptr)
    // {
        // std::cout<<"error, WidgetVariantContainer::slotSelectItemBase, ibp=nulptr"<<"\n";
        // return;
    // }

    // for(int i = ibp->getPropertyCount()-1 ; i >= 0; i--)
    // {
        // EItemMetaPropertyPtr p = ibp->getProperty(i);
        // WidgetVariant* wv = WidgetVariantFunction::createWidgetVariant(p->typeName);
        // if(wv != nullptr)
        // {
            // wv->refreshByProperty(p);
            // this->addWidget(wv);
        // }
    // }

    // this->installEventFilterForChildren();
}

void WidgetVariantContainer::slotDisSelectItemBase(EItemPtr ibp)
{
    std::cout<<"WidgetVariantContainer::slotSelectItemBase"<<"\n";
}

void WidgetVariantContainer::slotSubVariantWidgetChanged(EItemMetaPropertyPtr p)
{
    // if(m_itemBasePtr != nullptr)
    // {
        // m_itemBasePtr->updateToOrig(p->name);
        // emit signalPropertyChanged(m_itemBasePtr, p);
    // }
    // else
    // {
        // std::cout<<"error, WidgetVariantContainer::slotSubVariantWidgetChanged, m_itemBasePtr=nullptr\n";
    // }
}

void WidgetVariantContainer::slotButtonRefresh(bool boolValue)
{
    // if(m_itemBasePtr != nullptr)
    // {
        // m_itemBasePtr->updateToPropertyAll();
        // slotSelectItemBase(this->m_itemBasePtr);
    // }

}

void WidgetVariantContainer::slotButtonSearchClicked(bool boolValue)
{
    // std::cout<<"WidgetVariantContainer::slotButtonSearchClicked, fliterStr="<<ui->lineEdit->text().toStdString()<<std::endl;
    this->filtWidget(ui->lineEdit->text());
}

void WidgetVariantContainer::slotClearAll()
{
    this->cleanAllWidget();
}

bool WidgetVariantContainer::eventFilter(QObject* target, QEvent* event)
{
    bool result = false;
    if(event->type() == QEvent::Wheel)
    {
        result = true;
    }
    return result;
}
/*void WidgetVariantContainer::buildFromModule(Module* modulePtr)
{
    //先加入总体的group，如果module有name这个变量，则会生成一个group，主要是用于module作为成员变量的情况o
    if(modulePtr->getPropertyValueByName("name").toString().size() != 0)
    {
        WidgetVariantGroup* group = WidgetVariantFunction::createWidgetVariantGroup(modulePtr->getPropertyValueByName("name").toString() +":");
        addWidget(group);
    }

    //遍历属性
    QMap<QString, WidgetVariantGroup*> mapGroup;
    for(int i = 0 ; i < modulePtr->getPropertySize(); i++)
    {
        Property p = modulePtr->getPropertyByIndex(i);

        //如果属性不用于展示在ui上，则直接跳过去o
        if(p.ifShowUI == false)
        {
            continue;
        }

        //先生成group
        WidgetVariantGroup* group = NULL;
        if(p.groupName.size() != 0 && mapGroup.contains(p.groupName) == false)
        {
            group = WidgetVariantFunction::createWidgetVariantGroup(modulePtr->getPropertyValueByName("name").toString() +"-"+ p.groupName);
            addWidget(group);
            mapGroup[p.groupName] = group;
        }
        else if(p.groupName.size() != 0 && mapGroup.contains(p.groupName))
        {
            group = mapGroup[p.groupName];
        }
        // std::cout<<"Debug WidgetVariantContainer::buildFromModule group="<<group<<std::endl;
        //
        // 生成widgetvariant
        if(p.typeName == "Module*")
        {
            Module* subModulePtr = (Module*)p.value.value<void*>();
            // group = WidgetVariantFunction::createWidgetVariantGroup(p.groupName);
            // addWidget(group);
            buildFromModule(subModulePtr);
        }
        else
        {
            QList<WidgetVariant*> widgetList = WidgetVariantFunction::createWidgetVariant(modulePtr->getPropertyValueByName("name").toString(), p);
            for(int k = 0 ; k < widgetList.size(); k++)
            {
                WidgetVariant* widgetPtr = widgetList[k];
                addWidget(widgetPtr);
                QObject::connect(widgetPtr, SIGNAL(signalVariantChanged(const QString&, const QString& , const QVariant& )),
                              this, SLOT(slotVariantChanged(const QString& , const QString& , const QVariant&)));
                if(group != NULL)
                {
                    group->addChildVariant(widgetPtr);
                }
            }
        }
    }

    //设置局部过滤信息o
    for(int i = 0 ; i < modulePtr->getPropertySize(); i++)
    {
        Property p =  modulePtr->getPropertyByIndex(i);
        if(p.typeName == "enum")
        {
            WidgetVariant* w = dynamic_cast<WidgetVariant*>(this->findWidgetByPropertyName(p.name));
            //如果enum上存储的子widget名称列表为空，则跳过o
            if(p.enumAffectPropertyNames.size() != p.enumNames.size())
            {
                continue;
            }

            for(int j = 0 ; j < p.enumNames.size(); j++)
            {
                // std::cout<<"Debug WidgetVariantContainer::buildFromModule ["<<j<<"]"<<std::endl;
                for(int k = 0 ; k < p.enumAffectPropertyNames[j].size(); k++)
                {
                    // std::cout<<"Debug WidgetVariantContainer::buildFromModule enumAffectPropertyNames["<<j<<"]["<<k<<"]="<<p.enumAffectPropertyNames[j][k].toStdString()<<std::endl;
                    WidgetVariant* subW = dynamic_cast<WidgetVariant*>(this->findWidgetByPropertyName(p.enumAffectPropertyNames[j][k]));
                    subW->addFiltStr(p.enumNames[j]);
                    w->addFiltChildWidget(subW);
                }
            }
        }
    }

    //执行局部过滤，完成整个属性界面的初始化o
    for(int i = 0 ; i < modulePtr->getPropertySize(); i++)
    {
        Property theProperty = modulePtr->getPropertyByIndex(i);
        WidgetVariant* wv = dynamic_cast<WidgetVariant*>(this->findWidgetByPropertyName(theProperty.name));
        if(wv != NULL )
        {
            wv->performFilt();
        }
    }
}*/

// QWidget* WidgetVariantContainer::findWidgetByPropertyName(const QString& name)
// {
    // QWidget* wFound = NULL;
    // // for(int i = 0 ; i < m_widgetList.size(); i++)
    // // {
        // // WidgetVariant* wv = dynamic_cast<WidgetVariant*>(m_widgetList[i]);
        // // if(wv != NULL)
        // // {
            // // if(wv->getProperty().name == name)
            // // {
                // // wFound = wv;
            // // }
        // // }
    // // }
    // return wFound;
// }


/*void WidgetVariantContainer::slotModuleSelected(Module* modulePtr)
{
    //std::cout<<"Debug WidgetVariantContainer::slotModuleSelected"<<std::endl;
	cleanAllWidget();
    buildFromModule(modulePtr);
    m_currentModule = modulePtr;
	//std::cout << "WidgetVariantContainer::count = "<<m_layout->count() << std::endl;
}*/

